<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .box {
            width: 200px;
            height: 40px;
            line-height: 40px;
            margin: 0 auto;
        }

        .box span {
            display: block;
            height: 40px;
            border: solid 1px black;
            text-align: center;

        }

        ul {
            margin: 0 auto;
            padding: 0;
            list-style: none;
            display: none;
            text-align: center;
        }

        ul li {
            text-indent: 4px;
        }

        ul .hoveStyle {
            background-color: springgreen;
            color: whitesmoke
        }

        .box ul li#active::after {
            content: "√";
            margin-left: 20px;;

        }
    </style>
</head>
<body>
<select>
    <option></option>
    <option></option>
    <option></option>
    <option></option>
    <option></option>
    <option></option>
    <option></option>
    <option></option>
</select>
<div class="box">
    <span>选中的项</span>
    <ul>
        <li>上海</li>
        <li>北京</li>
        <li>杭州</li>
        <li>苏州</li>
        <li>浙江</li>
        <li>无锡</li>
        <li>深圳</li>
        <li>广东</li>
    </ul>
</div>
<script>
    let ospan = document.querySelector("span")

    let oul = document.querySelector("ul")
    let oli = document.querySelectorAll("li")
    console.log(oli)
    // 默认选中项的索引
    let index = 0
    ospan.innerHTML = oli[index].innerHTML;
    oli[index].id = "active"
    let flag = 0
    // 点击span标签让下面的ul标签显示
    ospan.onclick = function (e) {
        e.stopPropagation()
        if (flag === 0) {
            oul.style.display = "block"
            flag = 1
            keyIndex = undefined
        } else {
            oul.style.display = "none"
            flag = 0
        }
    }
    // 点击空白处让ul隐藏掉
    document.onclick = function () {
        oul.style.display = "none"
        flag = 0
    }
    // 循环每一个li 在绑定事件
    for (let i = 0; i < oli.length; i++) {
        oli[i].index = i
        // 鼠标移动的时候让经过的li标签改变样式
        oli[i].onmouseover = function () {
            this.className = "hoveStyle"
            keyIndex = this.index
        }
        // 离开后要是恢复
        oli[i].onmouseout = function () {
            this.className = ""
            if (keyIndex !== undefined) {
                oli[keyIndex].className = ""
            }
            keyIndex = undefined
        }
        // 点击li 的时候让span标签的内容改变成 li的里面的内容
        oli[i].onclick = function () {
            ospan.innerHTML = this.innerHTML
            oli[index].id = ""
            this.id = "active"
            index = this.index
        }
    }


    // 键盘
    let keyIndex = undefined
    // 创建一个键盘事件
    document.onkeydown = function (eve) {
        if (flag === 0) {
            return
        }
        let e = eve || window.event
        let code = e.keyCode || e.which

        // 这里是上键
        if (code === 38) {
            if (keyIndex === undefined) {
                keyIndex = 0
            } else if (keyIndex === 0) {
                keyIndex = oli.length - 1
            } else {
                keyIndex--
            }
            // 这里改变样式
            setKey(keyIndex)
        }
        // 这里是下贱
        if (code === 40) {
            if (keyIndex === undefined) {
                keyIndex = 0
            } else if (keyIndex === oli.length - 1) {
                keyIndex = oli.length - 1
            } else {
                keyIndex++
            }
            // 这里改变样式
            setKey(keyIndex)
        }
        if (code === 13) {
            ospan.innerHTML = oli[keyIndex].innerHTML
            oli[index].id = ""
            oli[keyIndex].id = "active"
            index = oli[keyIndex].index
        }
    }

    function setKey(theValue) {
        for (let i = 0; i < oli.length; i++) {
            oli[i].className = ""
        }
        oli[theValue].className = "hoveStyle"
    }

</script>
</body>
</html>